/*
 * 
 * Copyright 2010 David H Pollack
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 * 
 * 
 */

package com.dhpollack.rotogss.servlets;

import java.io.IOException;
import java.util.Collections;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.oauth.OAuthException;
import net.sf.jsr107cache.Cache;
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheFactory;
import net.sf.jsr107cache.CacheManager;

import com.dhpollack.rotogss.data.AppConfig;
import com.dhpollack.rotogss.data.RotoGSSUsers;
import com.dhpollack.rotogss.helper.AppHelper;
import com.dhpollack.rotogss.helper.PMF;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.simpleyql.Api;
import com.simpleyql.ApiFactory;
import com.simpleyql.QueryResult;

/**
 * @author davidpl
 * 
 * This servlet may be used for async requests from Yahoo.
 * Specifically for getting the league standings daily or really any
 * of the daily calls that need to be made to Yahoo.
 * 
 * 7/27/2010: Right now I am not using it. 
 *
 */
public class FantasyApiServlet extends HttpServlet {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 7736444602405362049L;
	
	private AppConfig APP_CONFIG = AppHelper.get();

	public void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
		doPost(req, resp);
	}
	
	public void doPost(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {

		String error;

		String user = req.getParameter("user");
		
		if(user == null) {
			log("No user set");
        	error = "<xml><error>No user set</error></xml>";
        	resp.getWriter().print(error);
			return;
		}

		String url = req.getParameter("url");
		
		if(url == null) {
			log("No URL set");
        	error = "<xml><error>No URL set</error></xml>";
        	resp.getWriter().print(error);
			return;
		}
		
		String passcode = req.getParameter("passcode");
		
		if(passcode == null) {
			log("No Passcode set");
        	error = "<xml><error>No Passcode set</error></xml>";
        	resp.getWriter().print(error);
			return;
		} else {
	        Cache cache;

	        try {
	            CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
	            cache = cacheFactory.createCache(Collections.emptyMap());
	            if(!cache.containsKey(passcode)) {
	            	log("JCache Passcode Not Found");
	            	error = "<xml><error>JCache Passcode Not Found</error></xml>";
	            	resp.getWriter().print(error);
	            	return;
	            } else {
		            if(!user.equals((String) cache.get(passcode))) {
		            	log("Passcode does not match user");
		            	error = "<xml><error>Passcode does not match user</error></xml>";
		            	resp.getWriter().print(error);
		            	return;
		            }
		            

	            }
	        } catch (CacheException e) {
	            // ...
	        }
		}

		String yahoo_xml = callYahooFantasy(user, url);
		
		resp.setContentType("text/xml");
		resp.getWriter().print(yahoo_xml);

	}
	
	private String callYahooFantasy(String user, String url)
	throws IOException {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		
		RotoGSSUsers rotogss_user;
		Key rotogss_userkey = new KeyFactory.Builder(RotoGSSUsers.class.getSimpleName(),user).getKey();
		try {
			rotogss_user = pm.getObjectById(RotoGSSUsers.class, rotogss_userkey);
		} catch(JDOObjectNotFoundException e) {
			log("No user found for " + user);
			log("Key used: " + rotogss_userkey.toString());
			return "<xml><error>UserNotFoundFailure</error></xml>";
		}
		
		String YAHOO_CONSUMER_KEY = APP_CONFIG.getYahooConsumerKey();
		String YAHOO_CONSUMER_SECRET = APP_CONFIG.getYahooConsumerSecret();
		String SIMPLEYQL_CALLBACK_SERVLET = APP_CONFIG.getBaseUrl() + "/simpleyqlcallback/";
		
		Api api = ApiFactory.getApiInstance(
				YAHOO_CONSUMER_KEY,
	            YAHOO_CONSUMER_SECRET,
	            SIMPLEYQL_CALLBACK_SERVLET,
	            false, null);
		
		QueryResult qr = null;
		
		String authdata = rotogss_user.getYahooOAuthData();
		
		log(rotogss_user.getGoogleUserKey().getName());
		log("Sending following request: \n" + url);
		
		try {
			qr = api.query2(url, authdata);
		} catch (OAuthException e) {
			log("Error posting to Y!:", e);
			return "<xml><error>OAuthException</error></xml>";
		} catch (RuntimeException e) {
			if (e.getMessage().equals("Unable to complete the HTTP request")) {
				if (e.getCause().getMessage()
						.contains("Timeout while fetching")) {
					log("Unable to complete Yahoo! query", e);
				} else {
					log("Error posting to Y!:", e);
					return "<xml><error>Error posting to Yahoo</error></xml>";
				}
			} else {
				throw e;
			}
		}
		
	    String xml = qr.getText();

	    // Update token, if needed (for future requests)
	    if (qr != null && !qr.getAuthdata().equals(rotogss_user.getYahooOAuthData())) {
	    	rotogss_user.setYahooOAuthData(qr.getAuthdata());
	    	try {
	    		pm.makePersistent(rotogss_user);
	    	} finally {
	    		pm.close();
	    	}
	    }
	    
	    if(!pm.isClosed()) {
	    	pm.close();
	    }

	    log("XML Length: " + xml.length());
	    return xml;
		
	}
	
}
